home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagn_r.zip / REDIRECT.SWG / 0008_EXEC with i-o redirection.pas < prev   
Pascal/Delphi Source File  |  1994-08-25  |  5KB  |  213 lines

  1. {
  2. From: Matthew.Mastracci@matrix.cpubbs.cuug.ab.ca (Matthew Mastracci)
  3.  
  4.  tf> A simple example:
  5.  tf> SwapVectors;
  6.  tf> Exec (GetEnv('comspec'), '/c dir *.* > FileName');
  7.  tf> SwapVectors;
  8.  
  9. This is a good way to do redirection for directory listings and the like,
  10. but a better way is to use this unit:  (I wrote it from an idea given to me by
  11. someone else posting the same sort of this, except this one includes error
  12. checking and containm much more useful procedures)  From this, you can go:
  13.  
  14. SwapVectors;
  15. RedirectOutput('\DIRLIST.TXT');
  16. Exec(GetEnv('COMSPEC'), '/C DIR *.*');
  17. StdOutput;
  18. SwapVectors;
  19.  
  20. Same thing, but more control...
  21.  
  22. Here's my REDIR.PAS unit:
  23.  
  24.   Redirection unit
  25.  
  26.   - Original author unknown, rewritten by Matthew Mastracci
  27.   - Added a bit of asm, pipe support, some better file handling ability, more
  28.      flexibility
  29.   - If you'd like some information on this program, E-Mail me at:
  30.      madhacker@matrix.cpubbs.cuug.ab.ca
  31.   - Feel free to distribute this source anywhere! (Public Domain)
  32. }
  33.  
  34. unit Redir;
  35.  
  36. interface
  37.  
  38. { Redirects standard input from a textfile/device  ie: command < filename }
  39. procedure RedirectInput(TextFile : String);
  40.  
  41. { Redirects standard output to a textfile/device  ie: command > filename }
  42. procedure RedirectOutput(TextFile : String);
  43.  
  44. { Redirects standard error to a textfile/device }
  45. procedure RedirectError(TextFile : String);
  46.  
  47. { Redirects standard output and error to a textfile/device }
  48. procedure RedirectAllOutput(TextFile : String);
  49.  
  50. { Redirects all I/O from a textfile  ie: ctty device }
  51. procedure RedirectAll(TextFile : String);
  52.  
  53. { Restores STDIN to CON }
  54. procedure StdInput;
  55.  
  56. { Restores STDOUT to CON }
  57. procedure StdOutput;
  58.  
  59. { Restores STDERR to CON }
  60. procedure StdError;
  61.  
  62. { Creates a unique file and returns its name (used for piping) }
  63. function UniqueFile : String;
  64.  
  65. implementation
  66.  
  67. uses Dos;
  68.  
  69. var InFile, OutFile, ErrFile : Text;
  70.  
  71. const
  72.   STDIN  = 0;       { Standard Input }
  73.   STDOUT = 1;       { Standard Output }
  74.   STDERR = 2;       { Standard Error }
  75.   Redirected : array[0..2] of Boolean = (False, False, False);
  76.  
  77. { Duplicates a file handle }
  78. procedure ForceDup (Existing, Second : Word);
  79. var f, Error : Word;
  80. begin
  81.   asm
  82.     mov ah, $46
  83.     mov bx, Existing
  84.     mov cx, Second
  85.     int $21
  86.     pushf
  87.     pop bx
  88.     mov f, bx
  89.     mov Error, ax
  90.   end;
  91.   if (f and FCarry) <> 0 then
  92.     Writeln ('Error ', Error, ' changing handle ', Second);
  93. end;
  94.  
  95. { Redirects standard input from a textfile/device  ie: command < filename }
  96. procedure RedirectInput(TextFile : String);
  97. begin
  98.   if Redirected[STDIN] then StdInput;
  99.   Redirected[STDIN] := True;
  100.   Assign(InFile, TextFile);
  101.   Reset(InFile);
  102.   ForceDup(TextRec(InFile).Handle, STDIN);
  103. end;
  104.  
  105. { Redirects standard output to a textfile/device  ie: command > filename }
  106. procedure RedirectOutput(TextFile : String);
  107. begin
  108.   if Redirected[STDOUT] then StdOutput;
  109.   Redirected[STDOUT] := True;
  110.   Assign(OutFile, TextFile);
  111.   Rewrite(OutFile);
  112.   ForceDup(TextRec(OutFile).Handle, STDOUT);
  113. end;
  114.  
  115. { Redirects standard error to a textfile/device }
  116. procedure RedirectError(TextFile : String);
  117. begin
  118.   if Redirected[STDERR] then StdError;
  119.   Redirected[STDERR] := True;
  120.   Assign(ErrFile, TextFile);
  121.   Rewrite(ErrFile);
  122.   ForceDup(TextRec(ErrFile).Handle, STDERR);
  123. end;
  124.  
  125. { Redirects standard output and error to a textfile/device }
  126. procedure RedirectAllOutput(TextFile : String);
  127. begin
  128.   RedirectOutput(TextFile);
  129.   RedirectError(TextFile);
  130. end;
  131.  
  132. { Redirects all I/O from a textfile  ie: ctty device }
  133. procedure RedirectAll(TextFile : String);
  134. begin
  135.   RedirectInput(TextFile);
  136.   RedirectOutput(TextFile);
  137.   RedirectError(TextFile);
  138. end;
  139.  
  140. { Restores STDIN to CON }
  141. procedure StdInput;
  142. begin
  143.   if Redirected[STDIN] then begin
  144.     Redirected[STDIN] := False;
  145.     RedirectInput('CON');
  146.     Close(InFile);
  147.   end;
  148. end;
  149.  
  150. { Restores STDOUT to CON }
  151. procedure StdOutput;
  152. begin
  153.   if Redirected[STDOUT] then begin
  154.     Redirected[STDOUT] := False;
  155.     RedirectOutput('CON');
  156.     Close(OutFile);
  157.   end;
  158. end;
  159.  
  160. { Restores STDERR to CON }
  161. procedure StdError;
  162. begin
  163.   if Redirected[STDERR] then begin
  164.     Redirected[STDERR] := False;
  165.     RedirectOutput('CON');
  166.     Close(OutFile);
  167.   end;
  168. end;
  169.  
  170. function UniqueFile : String;
  171. const FName : array[1..20] of Char = '\' + #0 + '                  ';
  172. var FSeg, FOfs : Word;
  173.     FileName : String;
  174. begin
  175.   FSeg := Seg(FName);
  176.   FOfs := Ofs(FName) + 1;
  177.   asm
  178.     push ds
  179.     mov ax, FSeg
  180.     mov ds, ax
  181.     mov dx, FOfs
  182.     mov ah, $5a
  183.     mov cx, 0
  184.     int $21
  185.     pop ds
  186.   end;
  187.   Move(FName, FileName[1], 9);
  188.   FileName[0] := #9;
  189.   UniqueFile := FileName;
  190. end;
  191.  
  192. end.
  193.  
  194. { This is how you can do piping.  It is equivilent to: }
  195. { type \autoexec.bat | find "ECHO" | sort /R }
  196.  
  197. {$M $1000,0,0}
  198. program PipeDemo;
  199. uses Redir, Dos;
  200. var FName : String;
  201.  
  202. begin
  203.   FName := UniqueFile;
  204.   WriteLn('Temporary file: ', FName);
  205.   WriteLn('Output from pipe:');
  206.   RedirectInput('\AUTOEXEC.BAT');
  207.   RedirectOutput(FName);
  208.   Exec('C:\DOS\FIND.EXE', '"ECHO"');
  209.   RedirectInput(FName);
  210.   RedirectOutput('CON');
  211.   Exec('C:\DOS\SORT.EXE', '/R');
  212. end.
  213.